package org.spruice;

import org.picocontainer.DefaultPicoContainer;
import org.spruice.proxy.ProxyCreator;
import org.spruice.reflect.StringToValue;

import java.util.ArrayList;
import java.util.List;

public class Binder {

    private final List<ContextEntry> builders = new ArrayList<ContextEntry>();
    private final ProxyCreator proxy = new ProxyCreator();
    private final AutoNamer autoNamer;
    private StringToValue converters;

    public Binder(AutoNamer namer, StringToValue converters) {
        this.autoNamer = namer;
        this.converters = converters;
    }

    public <T> BeanConfig<T> autowire(Class<T> clzz) {
        return autowire(autoNamer.next(clzz), clzz);
    }

    public <T> BeanConfig<T> autowire(String name, Class<T> clzz) {
        BeanDefinitionBuilder builder = new BeanDefinitionBuilder(name, clzz, null, converters);
        BeanConfig<T> config = new BeanConfig<T>(builder, proxy, clzz);
        builders.add(config);
        return config;
    }

    public <T> BeanConfig<T> register(final T instance) {
        Class<T> clzz = (Class<T>) instance.getClass();
        String name = autoNamer.next(clzz);
        BeanDefinitionBuilder builder = new BeanDefinitionBuilder(name, clzz, instance, converters);
        BeanConfig<T> config = new BeanConfig<T>(builder, proxy, clzz);
        builders.add(config);
        return config;

    }

    public NamedBean register(final String name, final Object singleton) {
        ContextEntry entry = new ContextEntry() {
            public void addTo(DefaultPicoContainer context, ModuleLifecycle life) {
                context.addComponent(name, singleton);
            }
        };
        builders.add(entry);
        return new NamedBean() {
            public String getName() {
                return name;
            }
        };
    }

    List<ContextEntry> getConfigs() {
        return builders;
    }
}
